home *** CD-ROM | disk | FTP | other *** search
- /* Screen Clock /Reminder.
- -----------------------
-
- Roger Dalton of R&D Associates.
-
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <bios.h>
- #include <time.h>
-
- #include "tsrlib.h"
-
-
- /* Table must exist! */
-
- HOTKEY hotkey_table[] = {
- KEYCODE(52, CTRL | ALT), /* CTRL-ALT-'.' */
- LAST_KEY /* no hotkeys needed */
- };
-
-
- /* Signature must exist! */
-
- char signature[] = "REMINDER";
-
-
- /* Structure to hold DOS time. */
-
- typedef struct {
- int hour;
- int min;
- int sec;
- int hsec;
- } TIMES;
-
-
- /* Specify only what you need. If you won't need a heap, specify a
- small value like this as 0 means 'use all possible'. NOTE: Turbo C2.0
- users can't specify less than about 512 anyway! */
-
- unsigned int _heaplen = 512;
- unsigned int _stklen = 512;
-
-
- unsigned int far *screen; /* pointer to video screen */
-
- char screen_save[8000]; /* screen save buffer */
-
- char alarm_time[6]; /* buffer for alarm time */
- char alarm_message[36]; /* buffer for alarm message */
-
- int alarm_set = 0;
- int alarm_hour = 0;
- int alarm_min = 0; /* current alarm time */
-
- /* PROTOTYPES */
-
- void get_time(TIMES *timerp);
- int get_mode(void);
- void get_user_alarm_time(void);
- void do_alarm(void);
- void draw_box(int r1, int c1, int r2, int c2, int attr);
- int get_string(int row, int col, char *buf, int size, int attr);
- void draw_string(int row, int col, char *string, int attr);
- void write_at(int row, int col, int *buf, int len);
- void set_cursor_style(int style);
- int get_cursor_style(void);
- int get_cursor_position(void);
- void set_cursor_position(int row, int col);
- void beep(void);
-
-
-
- /* The main program. The only possibilites are:
-
- remind foreground
- or
- remind foreground background
- */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- TIMES tim; /* time structure */
- int mode; /* video mode */
- unsigned int chr; /* buffer for characters */
- unsigned int attr = 0x7000; /* screen sttribute */
- int i; /* loop counter */
- int flip = 0; /* colon ticker */
- char tmp[32]; /* time string buffer */
- static char tick[] = ": ";
- int old_sec = 0;
-
- if (resident_tsr()) {
- printf("%s is already resident.\n", signature);
- exit(1);
- }
- printf("%s is loaded.\n", signature);
-
- if (argc > 1) {
- attr &= 0xf000;
- attr |= atoi(argv[1]) << 8;
- }
-
- if (argc > 2) {
- attr &= 0x0f00;
- attr |= atoi(argv[2]) << 12;
- }
-
- screen = (unsigned int far *)((get_mode() == 7)? 0xb0000000L: 0xb8000000L);
-
- /* Past here CAN'T use printf etc. */
-
- go_tsr(SLEEP, 1);
-
- while (1) {
- mode = get_mode();
- if (mode == 7 || mode == 3 || mode == 2) {
-
- if (mode == 7) {
- attr = 0x7000;
- }
-
- get_time(&tim);
- if (tim.sec != old_sec) {
- flip ^= 1; /* flip the colon */
- }
- old_sec = tim.sec;
- sprintf(tmp, " %02d%c%02d%c%02d %c ", tim.hour, tick[flip],
- tim.min, tick[!flip], tim.sec, " *"[alarm_set]);
-
- for (i = 0; (chr = tmp[i]); i++) {
- screen[35 + i] = chr | attr;
- }
-
- if (alarm_set && tim.hour >= alarm_hour && tim.min >= alarm_min) {
- do_alarm();
- }
- }
-
- /* If our hot key was pressed, save the screen as we will be writing on
- it. */
-
- if (suspend_tsr(SLEEP, 4) == RUNNING) {
- get_user_alarm_time();
- }
- }
- }
-
-
-
-
- /* Function to read DOS date & time, and build the structure. */
-
- void get_time(TIMES *timerp)
- {
- union REGS regs;
-
- regs.h.ah = 0x2c;
- int86(0x21, ®s, ®s);
- timerp->hour = regs.h.ch;
- timerp->min = regs.h.cl;
- timerp->sec = regs.h.dh;
- timerp->hsec = regs.h.dl;
- }
-
-
-
-
- /* Return the current display mode. */
-
- int get_mode(void)
- {
- _AH = 0x0f;
- geninterrupt(0x10);
- return _AL;
- }
-
-
-
- /* Procedure to draw a prompt box, and get an alarm time from the user. */
-
- void get_user_alarm_time(void)
- {
- char tmp[10];
-
- /* Save screen */
-
- movedata(FP_SEG(screen), 0, _DS, (unsigned)screen_save, 8000);
-
- draw_box(10, 15, 13, 65, 0x3000); /* black on cyan */
- draw_string(11, 17, "Alarm time: ", 0x3f00); /* bright white on cyan */
- draw_string(12, 17, " Message: ", 0x3f00); /* bright white on cyan */
- draw_string(12, 29, alarm_message, 0x3f00);
-
- /* Get the alarm time. */
-
- sprintf(alarm_time, "%02d:%02d", alarm_hour, alarm_min);
- do {
- beep();
- if (get_string(11, 29, alarm_time, sizeof(alarm_time) - 1, 0x3f00)) {
- goto done;
- }
- tmp[0] = alarm_time[0];
- tmp[1] = alarm_time[1];
- tmp[2] = '\0';
- tmp[3] = alarm_time[3];
- tmp[4] = alarm_time[4];
- tmp[5] = '\0';
- } while ((alarm_hour = atoi(tmp)) >= 24
- || (alarm_min = atoi(tmp + 3)) >= 60);
- alarm_set = 1;
-
- /* Get the alarm message. */
-
- get_string(12, 29, alarm_message, sizeof(alarm_message) - 1, 0x3f00);
-
- /* Restore screen */
- done:
- movedata(_DS, (unsigned)screen_save, FP_SEG(screen), 0, 8000);
- }
-
-
-
-
- /* Procedure to display the alarm time and message, and wait for ESCAPE to
- be pressed. */
-
- void do_alarm(void)
- {
- clock_t now;
- int toggle = 0;
- char tmp[40];
-
- _TS_tsr_state = RUNNING; /* don't pre-empt */
-
- /* Save screen */
-
- movedata(FP_SEG(screen), 0, _DS, (unsigned)screen_save, 8000);
-
- draw_box(10, 15, 13, 65, 0x4f00); /* bright white on red */
- sprintf(tmp, "*** ALARM AT %2d:%02d ***", alarm_hour, alarm_min);
- draw_string(11, 29, tmp, 0x4f00);
- sprintf(tmp, " Message: %s", alarm_message);
- draw_string(12, 17, tmp, 0x4f00);
-
- beep();
- now = clock();
- do {
- while (bioskey(1) == 0) {
- if (clock() >= now + 9 + toggle * 9) {
- beep();
- now = clock();
- toggle ^= 1;
- }
- }
- } while ((bioskey(0) & 0xff) != 0x1b);
-
- alarm_set = 0;
-
- /* Restore screen */
-
- movedata(_DS, (unsigned)screen_save, FP_SEG(screen), 0, 8000);
- }
-
-
-
-
- /* Procedure to draw a box from top left to bottom right. NOTE: to avoid sign
- extension on graphics characters, they must by masked with 0xff. This does not
- generate any more code. */
-
- void draw_box(int r1, int c1, int r2, int c2, int attr)
- {
- int i, j;
- int tmp[80]; /* draw buffer */
-
- j = c2 - c1 + 1;
- tmp[0] = attr | ('╔' & 0xff);
- for (i = 1; i < j - 1; i++) {
- tmp[i] = attr | ('═' & 0xff);
- }
- tmp[j - 1] = attr | ('╗' & 0xff);
- write_at(r1, c1, tmp, j);
- tmp[0] = attr | ('╚' & 0xff);
- tmp[j - 1] = attr | ('╝' & 0xff);
- write_at(r2, c1, tmp, j);
- tmp[0] = attr | ('║' & 0xff);
- tmp[j - 1] = attr | ('║' & 0xff);
- for (i = 1; i < j - 1; i++) {
- tmp[i] = attr | ' ';
- }
- for (i = r1 + 1; i < r2; i++) {
- write_at(i, c1, tmp, j);
- }
- }
-
-
-
-
- /* Procedure to read a string from the user at a given screen position. Returns
- when RETURN is pressed. */
-
- int get_string(int row, int col, char *buf, int size, int attr)
- {
- int key;
- int c;
- int old_pos = get_cursor_position();
- int old_style = get_cursor_style();
-
- c = 0;
- set_cursor_style(0x001f);
- for (;;) {
- set_cursor_position(row, c + col); /* position the cursor */
- buf[size] = '\0';
- draw_string(row, col, buf, attr);
- key = bioskey(0);
- if (key & 0xff) {
- key &= 0xff;
- if (key == 0x1b) {
- set_cursor_style(old_style);
- set_cursor_position(old_pos >> 8, old_pos);
- return 1; /* aborted by ESCAPE */
- }
- if (key >= ' ') {
- if (c < size) {
- buf[c] = key; /* standard ASCII keys */
- ++c;
- }
- } else if (key == '\r' || key == '\n') {
- set_cursor_style(old_style);
- set_cursor_position(old_pos >> 8, old_pos);
- return 0; /* done! */
-
- } else if (key == '\b') {
- if (c) {
- --c; /* backspace */
- }
- }
- } else {
- key >>= 8;
- if (key == 75) {
- if (c) {
- --c; /* left arrow */
- }
- } else if (key == 77) {
- if (c < size) {
- ++c; /* right arrow */
- }
- }
- }
- }
- }
-
-
-
-
- /* Procedure to draw a string on the screen. */
-
- void draw_string(int row, int col, char *string, int attr)
- {
- int i, t;
- int tmp[80];
-
- for (i = 0; i < 80; i++) {
- if ((t = *string++) == '\0') {
- break;
- }
- tmp[i] = attr | t;
- }
- write_at(row, col, tmp, i);
- }
-
-
-
-
- /* Procedure to write an array of cells to the screen. */
-
- void write_at(int row, int col, int *buf, int len)
- {
- unsigned int far *scp = &screen[row * 80 + col];
-
- while (len-- > 0) {
- *scp++ = *buf++;
- }
- }
-
-
-
-
- void set_cursor_style(int style)
- {
- int mode = get_mode();
-
- _AL = mode; /* avoid AMI 386 BIOS bug */
- _AH = 0x01;
- _CX = style;
- geninterrupt(0x10);
- }
-
-
-
-
- int get_cursor_style(void)
- {
- _BH = 0;
- _AH = 0x03;
- geninterrupt(0x10);
- return _CX;
- }
-
-
-
-
- int get_cursor_position(void)
- {
- _BH = 0;
- _AH = 0x03;
- geninterrupt(0x10);
- return _DX;
- }
-
-
-
-
- void set_cursor_position(int row, int col)
- {
- _BX = 0;
- _DH = row;
- _DL = col;
- _AH = 0x02;
- geninterrupt(0x10);
- }
-
-
-
-
- void beep(void)
- {
- _AX = 0x0e07;
- _BX = 0;
- geninterrupt(0x10);
- }
-